package materials.network;

import java.util.Set;

import materials.matrix.MatrixMaterialInterface;
import materials.neurons.Neurons;

/**
 * An Interface for a NeuronalNetwork
 * @author Sheepy
 *
 */
public interface NetworkInterface {
 //TODO Kommentare anpssen changed
	
	public double[] calculateNetworkInputVector(double[] _vector);
		
	public NetworkInterface clone();
	
	public void raiseLayer();
	/**
	 * Adds a Neuron to Specific Layer by the LayerNumber
	 * @param nmi - The Neuron which should be addded
	 * @param layer - Layer in which the Neuron should be added
	 * @require nmi != null
	 * @require hasLayer(layer) == true
	 * @ensure hasNeuron(nmi) == true
	 */
	public void addNeuron(int layer,String identifyer, String type);


	/**
	 * Returns the Weight-Matrix
	 * @return MatrixInterface - A Matrix which Contains all Weights of the Neurons
	 */
	public MatrixMaterialInterface getWeigthMatrix(int number);

	/**
	 * Returns the Connection-Matrix
	 * @return MatrixInterface - A Matrix which Contains the Connection Information of the Neurons
	 */
	public MatrixMaterialInterface getConnectionMatrix(int number);

	/**
	 * Returns the Number of Neurons in the Network
	 * @return int - Number of all Neurons in the Network
	 */
	public int getNeuronNumber();

	/**
	 * Returns the Numbers of the Layers
	 * 
	 * @return int -Numbers of Layers
	 */
	public int getLayerNumber();


	/**
	 * Returns the Weight from Neuron a to Neuron b
	 * @param na - Neuron where the Connection begins
	 * @param nb - Neuron where the Connection ends
	 * @param value - The new Weight between the Neurons
	 * @requires na != null
	 * @requires nb != null
	 * @requires na.getID() > 0
	 * @requires nb.getID() > 0
	 */
	public void setWeigthFromTo(int layer, String na,String nb, double value);


	/**
	 * Returns the Weight from Neuron a to Neuron b
	 * @param na - Neuron where the Connection begins
	 * @param nb - Neuron where the Connection ends
	 * @requires na != null
	 * @requires nb != null
	 * @requires na.getID() > 0
	 * @requires nb.getID() > 0
	 * @return double - The Weight from Neuron a to Neuron b
	 */
	public double getWeigthFromTo(int layer, String na,String nb);


	/**
	 * Sets the Connection from Neuron a to Neuron b
	 * @param na - Neuron where the Connection begins
	 * @param nb - Neuron where the Connection ends
	 * @requires na != null
	 * @requires nb != null
	 * @requires na.getID() > 0
	 * @requires nb.getID() > 0
	 */
	public void setConnectionFromTo(int layer, String na,String nb);

	/**
	 * Checks if two Neurons are Connected
	 * 
	 * @param na - Neuron where the Connection starts
	 * @param nb - Neuron where the Connection ends
	 * @requires na != null
	 * @requires nb != null
	 * @requires hasNeuron(na) == true
	 * @requires hasNeuron(nb) == true
	 * @return boolean - true if the Neurons are Connected
	 */
	public boolean hasConnectionFromTo(int layer,String na, String nb);

	/**
	 * Removes the Connection from Neuron a to Neuron b
	 * @param na - Neuron where the Connection begins
	 * @param nb - Neuron where the Connection ends
	 * @requires na != null
	 * @requires nb != null
	 * @requires na.getID() > 0
	 * @requires nb.getID() > 0
	 */
	public void removeConnectionFromTo(int layer, String na,String nb);


	/**
	 * Checks if the Network Contains the Neuron 
	 * @param id - NeuronID of the Neuron which might be in the Network
	 * @require nmi != null
	 * @require nmi.getID() > 0
	 * @return boolean - True if the Neuron is in the Network
	 */
	public boolean hasNeuron(String nmi);


	/**
	 * Checks if a Layer are Part of the Network
	 * 
	 * @param layer - Number of the Layer
	 * @require layer > 0
	 * @return - True if the Network contains the Layer
	 */
	public boolean hasLayer(int layer);

	
	public int getElementsInLayer(int i);
	
}
